package procsim;

public class MTriState implements Element{
    private Signal cSig;
    private MSignal inSig, result;
    protected boolean inverted = false;
    public MTriState(MSignal in, Signal c){
        if(in!=null) in.addElement(this);
        if(c!=null) c.addElement(this);
        inSig=in;
        cSig=c;
    }
    @Override
    public MTriState tick(){
        if(result==null || inSig==null) return this;
        if (cSig==null || (cSig!=null && cSig.isNull())) result.set(MSignal.HIGHZ);
        else if(inSig.get()==MSignal.HIGHZ && inSig.getNumOfBits()==1){
            result.set(1);
            if(inverted) result.not();
        }
        else{
            result.set(inSig);
            if(inverted) result.not();
        }
        return this;
    }
    @Override
    public MSignal result() {
        return result;
    }
    public MTriState setResult(MSignal sig){
        result=sig;
        return this;
    }
    public MTriState not(){
        inverted = Util.toggle(inverted);
        return this;
    }
    public boolean isInverted(){
        if(inverted) return true;
        else return false;
    }
    @Override
    public void updateSignal(Sig sig){
        boolean changed = false;
        if(inSig!=null && inSig==sig){
            inSig.set(sig.get(), false);
            changed = true;
        }
        if(cSig!=null && cSig==sig){
            cSig.set(sig.get(), false);
            changed = true;
        }
        if(changed) tick();
    }
}
